package io.github.wanggit.antrpc.gateway.starter.containers;

import io.github.wanggit.antrpc.commons.bean.AbstractHttpMethod;
import io.github.wanggit.antrpc.commons.bean.GetBean;
import io.github.wanggit.antrpc.commons.bean.HttpBean;
import io.github.wanggit.antrpc.commons.bean.PostBean;
import io.github.wanggit.antrpc.gateway.constants.Constants;
import io.vavr.Tuple;
import io.vavr.Tuple3;

import java.util.concurrent.ConcurrentHashMap;

public class HttpUrlContainer implements IHttpUrlContainer {

    private final ConcurrentHashMap<String, Tuple3<HttpBean, AbstractHttpMethod, String>>
            container = new ConcurrentHashMap<>();

    @Override
    public void add(HttpBean httpBean, GetBean getBean, String appName) {
        container.put(
                getKey(appName, Constants.HTTP_GET, httpBean.getValue(), getBean.getValue()),
                Tuple.of(httpBean, getBean, Constants.HTTP_GET));
    }

    @Override
    public void update(HttpBean httpBean, GetBean getBean, String appName) {
        add(httpBean, getBean, appName);
    }

    @Override
    public void remove(HttpBean httpBean, GetBean getBean, String appName) {
        container.remove(
                getKey(appName, Constants.HTTP_GET, httpBean.getValue(), getBean.getValue()));
    }

    @Override
    public void add(HttpBean httpBean, PostBean postBean, String appName) {
        container.put(
                getKey(appName, Constants.HTTP_POST, httpBean.getValue(), postBean.getValue()),
                Tuple.of(httpBean, postBean, Constants.HTTP_POST));
    }

    @Override
    public void update(HttpBean httpBean, PostBean postBean, String appName) {
        add(httpBean, postBean, appName);
    }

    @Override
    public void remove(HttpBean httpBean, PostBean postBean, String appName) {
        container.remove(
                getKey(appName, Constants.HTTP_POST, httpBean.getValue(), postBean.getValue()));
    }

    @Override
    public boolean contains(String appName, String method, String path) {
        return container.containsKey(methodAndUrl(appName, method, path));
    }

    @Override
    public Tuple3<HttpBean, AbstractHttpMethod, String> find(
            String appName, String method, String path) {
        return container.get(methodAndUrl(appName, method, path));
    }

    private String getKey(String appName, String method, String httpValue, String subValue) {
        return methodAndUrl(
                appName,
                method,
                (httpValue.startsWith("/") ? httpValue : "/" + httpValue)
                        + (httpValue.endsWith("/")
                                ? (subValue.startsWith("/") ? subValue.substring(1) : subValue)
                                : (subValue.startsWith("/") ? subValue : "/" + subValue)));
    }

    private String methodAndUrl(String appName, String method, String url) {
        return appName.toUpperCase() + " " + method.toUpperCase() + " " + url;
    }
}
